package com.lishui.waterfriend.controller;

import com.lishui.waterfriend.annotation.AuthCheck;
import com.lishui.waterfriend.annotation.JudgeEmpty;
import com.lishui.waterfriend.common.result.PageResult;
import com.lishui.waterfriend.common.result.Result;
import com.lishui.waterfriend.contant.MessageConstant;
import com.lishui.waterfriend.contant.UserConstant;
import com.lishui.waterfriend.context.BaseContext;
import com.lishui.waterfriend.enums.OperationTypeEnum;
import com.lishui.waterfriend.exception.DeletionNotAllowedException;
import com.lishui.waterfriend.exception.ParameterException;
import com.lishui.waterfriend.exception.UserNotLoginException;
import com.lishui.waterfriend.pojo.dto.PageDTO;
import com.lishui.waterfriend.pojo.dto.UserLoginDTO;
import com.lishui.waterfriend.pojo.dto.UserRegisterDTO;
import com.lishui.waterfriend.pojo.entity.User;
import com.lishui.waterfriend.pojo.vo.UserVO;
import com.lishui.waterfriend.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * 用户接口

 */
@RestController
@RequestMapping("/user")
@Slf4j
//@CrossOrigin(origins = {"http://localhost:5173"})
@Api(tags = "用户相关接口")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 用户注册
     *
     * @param userRegisterDTO
     * @return
     */
    @PostMapping("/register")
    @ApiOperation("用户注册")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result<Long> userRegister(@RequestBody UserRegisterDTO userRegisterDTO) {
        long result = userService.userRegister(userRegisterDTO);
        return Result.success(result);
    }

    /**
     * 用户登录
     *
     * @param userLoginDTO
     * @param request
     * @return
     */
    @PostMapping("/login")
    @ApiOperation("用户登录")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result<UserVO> userLogin(@RequestBody UserLoginDTO userLoginDTO, HttpServletRequest request) {
        String userAccount = userLoginDTO.getUserAccount();
        String userPassword = userLoginDTO.getUserPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new ParameterException(MessageConstant.EMPTY_PARAMETER);
        }
        UserVO userVO = userService.userLogin(userAccount, userPassword, request);
        return Result.success(userVO);
    }

    /**
     * 用户退出登录
     *
     * @param request
     * @return
     */
    @PostMapping("/logout")
    @ApiOperation("用户退出登录")
    public Result userLogout(HttpServletRequest request) {
        if (request == null) {
            throw new ParameterException(MessageConstant.EMPTY_PARAMETER);
        }
        userService.userLogout(request);
        return Result.success();
    }

    /**
     * 获取当前用户
     *
     */
    @GetMapping("/current")
    @ApiOperation("获取当前用户")
    public Result<UserVO> getCurrentUser() {
        UserVO currentUser = userService.getCurrentUser();
        return Result.success(currentUser);
    }

    /**
     * 查询用户列表
     * @param username
     * @return
     */
    @GetMapping
    @ApiOperation("管理员查询用户列表")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public Result<List<UserVO>> searchUsers(String username) {
        List<UserVO> userVOList = userService.searchUsers(username);
        return Result.success(userVOList);
    }

    /**
     * 删除用户
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    @ApiOperation("管理员根据Id删除用户")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result deleteUser(@PathVariable long id) {
        if (id <= 0) {
            throw new ParameterException(MessageConstant.USER_ID_EXCEPTION);
        }
        boolean flag = userService.removeUserById(id);
        if (!flag) throw new DeletionNotAllowedException(MessageConstant.DELETE_USER_FAILED);
        return Result.success();
    }

    /**
     * 根据标签分页查询用户
     * @param tagList
     * @return
     */
    @GetMapping("/search/tags")
    @ApiOperation("根据标签查询用户")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result<PageResult> searchUserByTagList(@RequestParam(required = false) List<String> tagList, Integer pageNum, Integer pageSize) {
        // return Result.success(userService.searchUserByTagListMemory(tagList));
        return Result.success(userService.searchUserByTagListSql(tagList, pageNum, pageSize));
    }

    @PutMapping
    @ApiOperation("修改用户信息")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result update(@RequestBody User user) {
        userService.update(user);
        return Result.success();
    }

    /**
     * 分页查询主页推荐获取用户
     * @return
     */
    @GetMapping("/recommend")
    @ApiOperation("获取推荐用户列表")
    public Result<PageResult> recommend(Integer pageNum, Integer pageSize) {
        // 缓存中有就从缓存中取
        Long currentUserId = BaseContext.getCurrentId();
        if (currentUserId == null) {
            throw new UserNotLoginException(MessageConstant.USER_NOT_LOGIN);
        }
        // 分别是 当前用户Id， 页码，一页用户数，作为redis的key
        String redisKey = String.format("waterfriend:user:recommend:%s:%s:%s", currentUserId, pageNum, pageSize);
        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
        PageResult pageResult = (PageResult) valueOperations.get(redisKey);
        if (pageResult != null) {
            return Result.success(pageResult);
        }
        log.info("获取推荐用户列表");
        pageResult = userService.PageQueryRecommendUser(pageNum, pageSize);
        // 没有就存到缓存里面，存储失败打印日志，但不影响返回
        try {
            valueOperations.set(redisKey, pageResult, 600000, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.info("redis set key error: {}", e.getMessage());
        }
        return Result.success(pageResult);
    }

    @GetMapping("/match")
    @ApiOperation("匹配用户")
    @JudgeEmpty(OperationTypeEnum.YES)
    public Result<PageResult> match(PageDTO pageDTO) {
        if (pageDTO == null) throw new ParameterException(MessageConstant.EMPTY_PARAMETER);
        PageResult pageResult = userService.PageQueryMatchUser(pageDTO);
        return Result.success(pageResult);
    }

}
